//
// Created by alexa on 5/11/2024.
//

#include "SoldiersMenu.h"
#include <iostream>
#include <conio.h>

#include "../../valid-input/ValidInput.h"
#include "../../keydown-handler/KeydownHandler.h"

using namespace std;

void SoldiersMenu::displayMenu() {
    printMenu();

    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this]() {
                ui->toggleLocale();
                return displayMenu();
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::MAIN_MENU);
                return;
            }},
            {Keys::KEY_1, [this]() {
                return displaySoldiersList();
            }},
            {Keys::KEY_2, [this]() {
                return findAndDisplaySoldierInfo();
            }},
            {Keys::KEY_3, [this]() {
                return createSoldier();
            }},
            {Keys::KEY_4, [this]() {
                Soldier *soldier = findSoldier();
                return deleteSoldier(soldier);
            }}
    });
}

void SoldiersMenu::createSoldier() {
    clearScreen();
    string firstname = vi::inputString((*t)("enter-firstname", "soldiers.create"));
    string surname = vi::inputString((*t)("enter-surname", "soldiers.create"));
    string rank = vi::inputString((*t)("enter-rank", "soldiers.create"));
    Specialization selectedSpecialization = selectSoldierSpecialization();
    Soldier *soldier = service->createOne(firstname, surname, rank,
                                          selectedSpecialization);

    return displaySoldierInfo(soldier);
}

Soldier *SoldiersMenu::findSoldier() {
    cout << endl;
    string soldierId = vi::inputString((*t)("enter-soldier-id", "soldiers.general"));
    try {
        return service->getById(soldierId);
    } catch (EntityNotFound &e) {
        cout << (*t)("soldier-doesnt-exist", "soldiers.general") << endl;
        cout << (*t)("continue", "general");
        _getch();
        ui->setCurrentPage(Pages::SOLDIERS_MENU);
        return nullptr;
    }
}

SoldiersMenu::SoldiersMenu(i18n::Translator *t, UserInterface *ui, SoldiersService *service) :
        Menu(t, ui),
        service(service) {
}

void SoldiersMenu::printMenu() {
    clearScreen();
    printKeybinds();
    cout << (*t)("title", "soldiers.main") << endl;
    cout << "1. " << (*t)("option1", "soldiers.main") << endl;
    cout << "2. " << (*t)("option2", "soldiers.main") << endl;
    cout << "3. " << (*t)("option3", "soldiers.main") << endl;
    cout << "4. " << (*t)("option4", "soldiers.main") << endl;
    cout << (*t)("select-action", "general",
                 {
                         {"min", "1"},
                         {"max", "4"}
                 });
}

void SoldiersMenu::printSoldierInfo(Soldier *soldier) {
    clearScreen();
    printKeybinds();
    cout << endl;
    cout << (*t)("id", "soldiers.info") << ": " << soldier->getId() << endl;
    cout << (*t)("fullname", "soldiers.info") << ": " << soldier->getFullname() << endl;
    cout << (*t)("rank", "soldiers.info") << ": " << soldier->getRank() << endl;
    cout << (*t)("specialization", "soldiers.info") << ": "
         << (*t)(specToString(soldier->getSpecialization()), "soldiers.specializations") << endl;
}

void SoldiersMenu::deleteSoldier(Soldier *soldier) {
    if (!soldier) return;
    string soldierId = soldier->getId();
    service->deleteOne(soldierId);
    cout << (*t)("successfully-deleted", "soldiers.delete", {{"soldier-id", soldierId}}) << endl;
    cout << (*t)("continue", "general") << endl;
    _getch();
    ui->setCurrentPage(Pages::SOLDIERS_MENU);
}

void SoldiersMenu::printSoldiersList(vector<Soldier *> list) {
    clearScreen();
    printKeybinds();
    cout << (*t)("title", "soldiers.list") << endl;
    if (list.empty()) {
        cout << (*t)("empty-list", "general") << endl;
        return;
    }
    for (auto &soldier: list) {
        cout << (*t)("id", "soldiers.info") << ": " << soldier->getId() << endl;
        cout << (*t)("fullname", "soldiers.info") << ": " << soldier->getFullname() << endl;
        cout << (*t)("rank", "soldiers.info") << ": " << soldier->getRank() << endl;
        cout << (*t)("specialization", "soldiers.info") << ": "
             << (*t)(specToString(soldier->getSpecialization()), "soldiers.specializations") << endl;
        cout << endl;
    }
}

void SoldiersMenu::displaySoldiersList() {
    vector<Soldier *> soldiers = service->getAll();
    printSoldiersList(soldiers);
    cout << endl << (*t)("get-info", "soldiers.list") << endl;
    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this]() {
                ui->toggleLocale();
                return displaySoldiersList();
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::SOLDIERS_MENU);
                return;
            }},
            {Keys::KEY_I, [this]() {
                return findAndDisplaySoldierInfo();
            }}
    });
}

void SoldiersMenu::displaySoldierInfo(Soldier *soldier) {
    if (!soldier) return;
    printSoldierInfo(soldier);
    cout << endl << (*t)("edit-rank", "soldiers.info") << endl;
    cout << (*t)("edit-spec", "soldiers.info") << endl;
    cout << (*t)("delete", "soldiers.info") << endl;
    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this, soldier]() {
                ui->toggleLocale();
                return displaySoldierInfo(soldier);
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::SOLDIERS_MENU);
                return;
            }},
            {Keys::KEY_D, [this, soldier]() {
                return deleteSoldier(soldier);
            }},
            {Keys::KEY_S, [this, soldier]() {
                Specialization selectedSpecialization = selectSoldierSpecialization();
                soldier->setSpecialization(selectedSpecialization);
                service->saveSoldier(soldier);
                return displaySoldierInfo(soldier);
            }},
            {Keys::KEY_R, [this, soldier]() {
                string newRank = vi::inputString((*t)("enter-rank", "soldiers.create"));
                soldier->setRank(newRank);
                service->saveSoldier(soldier);
                return displaySoldierInfo(soldier);
            }},
    });
}

void SoldiersMenu::findAndDisplaySoldierInfo() {
    Soldier *soldier = findSoldier();
    return displaySoldierInfo(soldier);
}

Specialization SoldiersMenu::selectSoldierSpecialization() {
    int chosenSpecialization = vi::inputList(
            {
                    (*t)("Commander", "soldiers.specializations"),
                    (*t)("Gunner", "soldiers.specializations"),
                    (*t)("MechanicDriver", "soldiers.specializations"),
                    (*t)("Charger", "soldiers.specializations")
            },
            (*t)("choose-specialization", "soldiers.create")
    );
    return static_cast<Specialization>(chosenSpecialization - 1);
}
